﻿using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Cmp;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Domain.DomainRepository;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Domain.LogDomain;
using Zocono.WCS.Domain.PlcBytesObject;
using Zocono.WCS.Domain.PlcConnectPoolDomain;
using Zocono.WCS.Domain.ProcessModuleDomain;
using Zocono.WCS.Domain.ScGetWMSTaskDomain;
using Zocono.WCS.Infrastructure.ApllicationDto.Enums;
using Zocono.WCS.Infrastructure.ApllicationDto.WCSTaskDto;
using Zocono.WCS.Infrastructure.PlcCommon;
using Zocono.WCS.WMSApiDomain;
using Zocono.WCS.WMSApiDomain.WebApi;

namespace Zocono.WCS.Domain.EquipmentProcessDomain.ScMessage
{
    /// <summary>
    /// 堆垛机
    /// </summary>
    public class ZJNScActionMessageService : IScActionMessageService
    {
        private readonly IPlcConnectionPoolService _plcConnectionPoolService;
        private readonly ILogUtil _logUtil;
        //private readonly IScMessageServiceFactory _scMessageServiceFactory;
        private readonly IScGetWMSTaskService _scGetWMSTaskService;
        private readonly ISnowflake _Snowflake;
        private readonly ITelegramRecordInfoRepository _TelegramRecordInfoRepository;
        private readonly IPlcConnectionStateInfoRepository _IPlcConnectionStateInfoRepository;
        private readonly IRunLogInfoService _IRunLogInfoService;

        private readonly IPlcReadDbInfoRepository _PlcReadeDbInfoRepository;
        private readonly IPlcConnectionPool _plcConnectionPool;
        private readonly IWorkTaskInfoRepository _WorkTaskInfoRepository;
        private readonly IPlcWriteDbInfoRepository _plcWriteDbInfoRepository;
        private static IInterfaceLogInfoService _IIterfaceLogInfoService;

        public ZJNScActionMessageService(IPlcConnectionPoolService plcConnectionPoolService,
            ILogUtil logUtil,
            //IScMessageServiceFactory scMessageServiceFactory,
            IScGetWMSTaskService scGetWMSTaskService,
            ISnowflake snowflake,
            ITelegramRecordInfoRepository telegramRecordInfoRepository
            , IPlcConnectionStateInfoRepository plcConnectionStateInfoRepository
            , IRunLogInfoService runLogInfoService
             , IPlcReadDbInfoRepository plcReadDbInfoRepository
              , IPlcConnectionPool plcConnectionPool
            , IWorkTaskInfoRepository workTaskInfoRepository
             , IPlcWriteDbInfoRepository plcWriteDbInfoRepository
            , IInterfaceLogInfoService iterfaceLogInfoService)
        {
            _plcConnectionPoolService = plcConnectionPoolService;
            _logUtil = logUtil;
            //_scMessageServiceFactory = scMessageServiceFactory;
            _scGetWMSTaskService = scGetWMSTaskService;
            _Snowflake = snowflake;
            _TelegramRecordInfoRepository = telegramRecordInfoRepository;
            _IPlcConnectionStateInfoRepository = plcConnectionStateInfoRepository;
            _IRunLogInfoService = runLogInfoService;

            _PlcReadeDbInfoRepository = plcReadDbInfoRepository;
            _plcConnectionPool = plcConnectionPool;
            _WorkTaskInfoRepository = workTaskInfoRepository;
            _plcWriteDbInfoRepository = plcWriteDbInfoRepository;
            _IIterfaceLogInfoService = iterfaceLogInfoService;
        }

        /// <summary>
        /// 堆垛机主页务
        /// </summary>
        /// <param name="scEquipmentDbObject"></param>
        /// <param name="puDoEquipmentDbObjects"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task ProcessActionMessageAsync(EquipmentDbObject scEquipmentDbObject,
            List<EquipmentDbObject> puDoEquipmentDbObjects)
        {
            //1、SC动作报文
            if (scEquipmentDbObject == null)
            {
                throw new Exception($"SC报文异常,报文为空");
            }
            if (scEquipmentDbObject.bytesObjectBases.Count == 0)
            {
                throw new Exception($"SC编号:{scEquipmentDbObject.EquipmentCode} 报文异常");
            }

            var plcActionMessages = scEquipmentDbObject.bytesObjectBases.Find(o => o.ObjectType.Contains("PlcActionBO"));
            ZJNScMessagePlcActionBO zJNScMessagePlcActionBO = plcActionMessages as ZJNScMessagePlcActionBO;
            var wcsActionMessages = scEquipmentDbObject.bytesObjectBases.Find(o => o.ObjectType.Contains("WcsActionBO"));
            ZJNScMessageWcsActionBO zJNScMessageWcsActionBO = wcsActionMessages as ZJNScMessageWcsActionBO;

            //_logUtil.Debug($"堆垛机{zJNScMessagePlcActionBO.EquipmentCode}开始轮询交互任务！");

            PlanarInventoryWriteWcsAction writeBo = null;
            PlcConnectionS7 plcConn = _plcConnectionPool.S7GetWritePlcConnection(plcActionMessages.PlcConnectionID);//plc写入连接（不锁定）

            RunLogInfo runLogInfo = new RunLogInfo();
            runLogInfo.ContainerBarcode = "不获取";
            runLogInfo.EquipmentCode = zJNScMessagePlcActionBO.EquipmentCode;
            runLogInfo.RunType = "堆垛机业务";



            //2、交接台状态报文
            List<PlanarStateBO> planarStateBOs = new List<PlanarStateBO>();
            PlanarStateBO planarStateBO = new PlanarStateBO();

            if (puDoEquipmentDbObjects != null && scEquipmentDbObject.bytesObjectBases != null && scEquipmentDbObject.bytesObjectBases.Count > 0)
            {
                foreach (var temp in puDoEquipmentDbObjects)
                {
                    var stateMessages = temp.bytesObjectBases.Find(o => o.ObjectType.Contains("StateBO"));
                    if (stateMessages != null)
                    {
                        planarStateBO = stateMessages as PlanarStateBO;

                        planarStateBOs.Add(planarStateBO);
                    }
                }
            }

            //盘点台状态报文
            PlanarInventoryBO inventoryStateBO = null;//新增盘点类
            if (puDoEquipmentDbObjects != null && scEquipmentDbObject.bytesObjectBases != null && scEquipmentDbObject.bytesObjectBases.Count > 0)
            {
                foreach (var temp in puDoEquipmentDbObjects)
                {
                    var stateMessages = temp.bytesObjectBases.Find(o => o.ObjectType.Contains("PlanarInventoryBO"));
                    if (stateMessages != null)
                    {
                        inventoryStateBO = stateMessages as PlanarInventoryBO;//新增盘点类    
                    }
                }
            }


            //_logUtil.Debug($"堆垛机{zJNScMessagePlcActionBO.EquipmentCode}开始轮询交互任务2！");

            if (_logUtil.LogOpen == "1")
            {
                _logUtil.Debug($"堆垛机:{zJNScMessagePlcActionBO?.EquipmentCode}|自动:{zJNScMessagePlcActionBO?.StackerHandAutomatic}|空闲:{zJNScMessagePlcActionBO?.StackerBusy}|完成信号:{zJNScMessagePlcActionBO?.StackerTaskCompletion}|任务号:{zJNScMessagePlcActionBO?.Currentjobnumber}");
            }

            if (zJNScMessageWcsActionBO != null && zJNScMessagePlcActionBO != null)
            {
                //_logUtil.Debug($"堆垛机{zJNScMessagePlcActionBO.EquipmentCode}开始轮询交互任务3！");
                #region SC当前空闲可执行作业（只发了启动的相关信息）
                if (zJNScMessagePlcActionBO.StackerHandAutomatic &&
                     zJNScMessagePlcActionBO.StackerBusy &&
                    !zJNScMessagePlcActionBO.StackerAlarm &&
                    !zJNScMessagePlcActionBO.Stackerrunningsignal &&
                    //zJNScMessagePlcActionBO.SecurityDooronLine && //TODO 68项目暂时安全门默认打开所以先移除安全门判断
                    !zJNScMessagePlcActionBO.Forkhasaterial &&
                    !zJNScMessageWcsActionBO.Startcommand)
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    if (_logUtil.LogOpen == "1")
                    {
                        _logUtil.Debug($"{zJNScMessagePlcActionBO?.EquipmentCode}下发任务开始");
                    }
                    //_logUtil.Debug($"堆垛机{zJNScMessagePlcActionBO.EquipmentCode}开始轮询交互任务4！");
                    var palletCodeCurrent = "";
                    try
                    {
                        //获取Sc写入Db
                        PlcWriteDbInfo plcWriteDbInfo = await _scGetWMSTaskService.ScGetPlcWriteDbInfoAsync(zJNScMessagePlcActionBO.EquipmentCode,
                            "ZJNScMessageWriteWcsActionBO");
                        //Sc使用Plc连接
                        var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);
                        if (plcservice == null)
                        {
                            runLogInfo.RunLog = $"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            _logUtil.Error(runLogInfo.RunLog);
                            return;
                        }
                        //1. 验证plc是否在线
                        var plcIPStates = await _IPlcConnectionStateInfoRepository.GetFirstAsync(l => l.PlcConnectionID == zJNScMessagePlcActionBO.PlcConnectionID && l.Connected == true);
                        if (plcIPStates == null)
                        {
                            runLogInfo.RunLog = "plc已离线";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            _logUtil.Error(runLogInfo.RunLog);
                            return;
                        }

                        //获取堆垛机任务
                        var wmstask = await _scGetWMSTaskService.ScGetFirstWorkTaskInfoAsync(zJNScMessagePlcActionBO.EquipmentCode, planarStateBOs);

                        ////从缓存获取堆垛机任务
                        //var wmstask = await _scGetWMSTaskService.ScGetCurrentTaskInfoAsync(zJNScMessagePlcActionBO.EquipmentCode, planarStateBOs);
                        if (wmstask == null)
                        {
                            runLogInfo.RunLog = "无任务";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            //_logUtil.Error(runLogInfo.RunLog);
                            _logUtil.Debug($"获取{zJNScMessagePlcActionBO.EquipmentCode}无任务");
                            return;
                        }
                        if (_logUtil.LogOpen == "1")
                        {
                            var type = string.Empty;
                            if (wmstask.CurrentDispatchType == EnumDispatchType.SC_UP)
                            {
                                type = "入库";
                            }
                            if (wmstask.CurrentDispatchType == EnumDispatchType.SC_DOWN)
                            {
                                type = "出库";
                            }
                            _logUtil.Debug($"获取{zJNScMessagePlcActionBO?.EquipmentCode}|{type}|{wmstask.TaskCode}找到任务");
                        }
                        palletCodeCurrent = wmstask.PalletCode;
                        //盘点模式 盘点位有料，不去取料
                        //inventoryStateBO.Reserve == 1 有料  == 0 无料
                        //inventoryStateBO.Reserve2 == 1 盘点模式  == 0 正常模式
                        if (inventoryStateBO != null && inventoryStateBO.Reserve == 1 && inventoryStateBO.Reserve2 == 1)
                        {
                            runLogInfo.RunLog = "盘点位有料，暂不执行任务";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            _logUtil.Error(runLogInfo.RunLog);

                            return;
                        }
                        if (wmstask.CurrentDispatchType == EnumDispatchType.SC_UP || wmstask.CurrentDispatchType == EnumDispatchType.SC_MOVE || wmstask.CurrentDispatchType == EnumDispatchType.SC_Fire)
                        {
                            ZJNScMessageWriteWcsActionBO wcsSendPlc = new ZJNScMessageWriteWcsActionBO();
                            if (wmstask.CurrentDispatchType == EnumDispatchType.SC_UP)
                            {
                                //入库
                                wcsSendPlc.Jobordercode = 1;
                                runLogInfo.RunLog = "上料任务开始";

                                runLogInfo.RunType = "堆垛机上料任务业务";
                            }
                            else if (wmstask.CurrentDispatchType == EnumDispatchType.SC_MOVE)
                            {
                                //巷道内移动
                                wcsSendPlc.Jobordercode = 3;
                                runLogInfo.RunLog = "库内移动任务开始";
                                runLogInfo.RunType = "堆垛机库内移动任务业务";

                            }
                            else
                            {
                                wcsSendPlc.Jobordercode = 5;
                                runLogInfo.RunLog = "消防任务开始";
                                runLogInfo.RunType = "堆垛机消防任务业务";
                            }
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);

                            wcsSendPlc.Startcommand = false;
                            wcsSendPlc.Alarmreset = true;
                            wcsSendPlc.Taskreset = false;
                            wcsSendPlc.WCSfirecommand = false;
                            if (wcsSendPlc.Jobordercode == 5)
                            {
                                wcsSendPlc.WCSfirecommand = true;
                            }
                            //新增//TODO此处临时修改
                            wcsSendPlc.WCSPhotoFire = false;
                            wcsSendPlc.WCSRgvFireHlper = false;
                            wcsSendPlc.WCSDTSAlarm = false;
                            wcsSendPlc.TimeReset = false;
                            wcsSendPlc.Jobnumber = wmstask.TaskCode;
                            //起点与终点坐标
                            wcsSendPlc.StartlinefromPC = Convert.ToInt16(wmstask.CurrentFromCargo.Substring(1, 3)) % 2 == 1 ? (short)1 : (short)2;
                            wcsSendPlc.StartcolumnfromPC = Convert.ToInt16(wmstask.CurrentFromCargo.Substring(4, 3));
                            wcsSendPlc.StartlayerfromPC = Convert.ToInt16(wmstask.CurrentFromCargo.Substring(7, 3));

                            wcsSendPlc.TargetlinefromPC = Convert.ToInt16(wmstask.CurrentToCargo.Substring(1, 3)) % 2 == 1 ? (short)1 : (short)2;
                            wcsSendPlc.TargetcolumnfromPC = Convert.ToInt16(wmstask.CurrentToCargo.Substring(4, 3));
                            wcsSendPlc.TargetlayerfromPC = Convert.ToInt16(wmstask.CurrentToCargo.Substring(7, 3));

                            wcsSendPlc.WCSpostingcompleted = 0;
                            wcsSendPlc.yuliu8 = 0;
                            wcsSendPlc.yuliu9 = 0;
                            wcsSendPlc.yuliu10 = 0;
                            wcsSendPlc.yuliu11 = 0;
                            wcsSendPlc.yuliu12 = 0;
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);


                            byte[] wcsBytess = wcsSendPlc.Deserialize();
                            bool flags = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsBytess);//写入PLC
                            Thread.Sleep(50);
                            wcsSendPlc.Startcommand = true;
                            //runLogInfo.RunLog = $"WCSBO{JsonConvert.SerializeObject(wcsSendPlc)}";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            byte[] wcsBytes = wcsSendPlc.Deserialize();
                            bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsBytes);//写入PLC
                            if (flag)
                            {
                                runLogInfo.RunLog = $"堆垛机发送入库任务WCS写入PLC成功，写入报文：{JsonConvert.SerializeObject(wcsSendPlc)}";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                wmstask.CurrentDetailTaskState = EnumDetailTaskState.Executing;
                                wmstask.CurrentUpdateTime = DateTime.Now;
                                wmstask.TaskState = EnumTaskState.Executing;
                                wmstask.UpdateTime = DateTime.Now;
                                await _scGetWMSTaskService.ScUpdateWorkTaskInfoAsync(wmstask);//更新任务信息
                                try
                                {
                                    //将任务状态同步到Wms
                                    await WCSMessageWithWMSApi.WCSUpdateWMStaskStateAndProcessTaskStateAsync(wmstask.WmsTaskCode, 2, 0);
                                }
                                catch (Exception ex)
                                {
                                    _logUtil.Error($"同步WMS任务【{wmstask.WmsTaskCode}】报错，ex = {ex.Message}");
                                    runLogInfo.RunLog = $"WCS更新WMS作业号：{wmstask.WmsTaskCode}任务为执行状态失败";
                                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                    _logUtil.Error(runLogInfo.RunLog);
                                }
                                runLogInfo.RunLog = $"WCS更新WMS作业号：{wmstask.WmsTaskCode}任务为执行状态成功";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);

                                ////插入到任务路径详细记录表
                                //TaskRouteDetailRecordInfo taskRouteDetailRecordInfo = new TaskRouteDetailRecordInfo();
                                //taskRouteDetailRecordInfo.TaskID = wmstask.ID;
                                //taskRouteDetailRecordInfo.RouteDetailID = wmstask.CurrentRounteDetailID;
                                //taskRouteDetailRecordInfo.DetailTaskState = EnumDetailTaskState.Executing;
                                //taskRouteDetailRecordInfo.DispatchType = wmstask.CurrentDispatchType;
                                //taskRouteDetailRecordInfo.FromEquipment = wmstask.CurrentFromEquipment;
                                //taskRouteDetailRecordInfo.FromCargo = wmstask.CurrentFromCargo;
                                //taskRouteDetailRecordInfo.ToEquipment = wmstask.CurrentToEquipment;
                                //taskRouteDetailRecordInfo.ToCargo = wmstask.CurrentToCargo;
                                //taskRouteDetailRecordInfo.CreateTime = wmstask.CurrentCreateTime;
                                //taskRouteDetailRecordInfo.UpdateTime = DateTime.Now;
                                //await _scGetWMSTaskService.InsertTaskRouteDetailRecordInfoAsync(taskRouteDetailRecordInfo);

                                //runLogInfo.RunLog = $"插入到任务路径详细记录表";
                                ////await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                //_logUtil.Error(runLogInfo.RunLog);

                            }

                            stopwatch.Stop();
                            if (_logUtil.LogOpen == "1")
                            {
                                var JobOrderCode = wcsSendPlc.Jobordercode == 1 ? "入库" : "移库";
                                _logUtil.Debug($"获取{zJNScMessagePlcActionBO?.EquipmentCode}下发任务完成|{JobOrderCode}|{stopwatch.ElapsedMilliseconds}");
                            }
                        }
                        else if (wmstask.CurrentDispatchType == EnumDispatchType.SC_CROSS || wmstask.CurrentDispatchType == EnumDispatchType.SC_DOWN)
                        {
                            ZJNScMessageWriteWcsActionBO wcsSendPlc = new ZJNScMessageWriteWcsActionBO();
                            wcsSendPlc.Startcommand = false;
                            wcsSendPlc.Alarmreset = true;
                            wcsSendPlc.Taskreset = false;
                            wcsSendPlc.WCSfirecommand = false;
                            wcsSendPlc.WCSPhotoFire = false;
                            wcsSendPlc.WCSRgvFireHlper = false;
                            wcsSendPlc.WCSDTSAlarm = false;
                            wcsSendPlc.TimeReset = false;
                            wcsSendPlc.Jobnumber = wmstask.TaskCode;

                            if (wmstask.CurrentDispatchType == EnumDispatchType.SC_CROSS)
                            {
                                runLogInfo.RunLog = "越库开始";
                                runLogInfo.RunType = "堆垛机越库任务业务";
                                wcsSendPlc.Jobordercode = 3;
                            }
                            else
                            {
                                runLogInfo.RunLog = "下料任务开始";
                                runLogInfo.RunType = "堆垛机下料任务业务";
                                wcsSendPlc.Jobordercode = 2;
                            }
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            //起点终点坐标
                            wcsSendPlc.StartlinefromPC = Convert.ToInt16(wmstask.CurrentFromCargo.Substring(1, 3)) % 2 == 1 ? (short)1 : (short)2;
                            wcsSendPlc.StartcolumnfromPC = Convert.ToInt16(wmstask.CurrentFromCargo.Substring(4, 3));
                            wcsSendPlc.StartlayerfromPC = Convert.ToInt16(wmstask.CurrentFromCargo.Substring(7, 3));
                            wcsSendPlc.TargetlinefromPC = Convert.ToInt16(wmstask.CurrentToCargo.Substring(1, 3)) % 2 == 1 ? (short)1 : (short)2;
                            wcsSendPlc.TargetcolumnfromPC = Convert.ToInt16(wmstask.CurrentToCargo.Substring(4, 3));
                            wcsSendPlc.TargetlayerfromPC = Convert.ToInt16(wmstask.CurrentToCargo.Substring(7, 3));

                            wcsSendPlc.WCSpostingcompleted = 0;
                            wcsSendPlc.yuliu8 = 0;
                            wcsSendPlc.yuliu9 = 0;
                            wcsSendPlc.yuliu10 = 0;
                            wcsSendPlc.yuliu11 = 0;
                            wcsSendPlc.yuliu12 = 0;


                            byte[] wcsBytess = wcsSendPlc.Deserialize();
                            bool flags = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsBytess);//写入PLC

                            Thread.Sleep(50);

                            wcsSendPlc.Startcommand = true;

                            //runLogInfo.RunLog = $"WCSBO{JsonConvert.SerializeObject(wcsSendPlc)}";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);


                            byte[] wcsBytes = wcsSendPlc.Deserialize();
                            bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsBytes);//写入PLC
                            if (flag)
                            {
                                runLogInfo.RunLog = $"堆垛机写入出库任务写入PLC成功，写入报文：{JsonConvert.SerializeObject(wcsSendPlc)}";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                wmstask.CurrentDetailTaskState = EnumDetailTaskState.Executing;
                                wmstask.CurrentUpdateTime = DateTime.Now;
                                wmstask.TaskState = EnumTaskState.Executing;
                                wmstask.UpdateTime = DateTime.Now;
                                await _scGetWMSTaskService.ScUpdateWorkTaskInfoAsync(wmstask);//任务更新到数据库
                                try
                                {
                                    //更新作业状态2为执行中，
                                    await WCSMessageWithWMSApi.WCSUpdateWMStaskStateAndProcessTaskStateAsync(wmstask.WmsTaskCode, 2, 0);
                                }
                                catch (Exception ex)
                                {
                                    _logUtil.Error($"同步WMS任务【{wmstask.WmsTaskCode}】报错，ex = {ex.Message}");
                                    runLogInfo.RunLog = $"WCS更新WMS作业号：{wmstask.WmsTaskCode}任务为执行状态失败";
                                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                    _logUtil.Error(runLogInfo.RunLog);
                                }

                                runLogInfo.RunLog = $"WCS更新WMS作业号：{wmstask.WmsTaskCode}任务为执行状态成功";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                //TaskRouteDetailRecordInfo taskRouteDetailRecordInfo = new TaskRouteDetailRecordInfo();
                                //taskRouteDetailRecordInfo.TaskID = wmstask.ID;
                                //taskRouteDetailRecordInfo.RouteDetailID = wmstask.CurrentRounteDetailID;
                                //taskRouteDetailRecordInfo.DetailTaskState = EnumDetailTaskState.Executing;
                                //taskRouteDetailRecordInfo.DispatchType = wmstask.CurrentDispatchType;
                                //taskRouteDetailRecordInfo.FromEquipment = wmstask.CurrentFromEquipment;
                                //taskRouteDetailRecordInfo.FromCargo = wmstask.CurrentFromCargo;
                                //taskRouteDetailRecordInfo.ToEquipment = wmstask.CurrentToEquipment;
                                //taskRouteDetailRecordInfo.ToCargo = wmstask.CurrentToCargo;
                                //taskRouteDetailRecordInfo.CreateTime = wmstask.CurrentCreateTime;
                                //taskRouteDetailRecordInfo.UpdateTime = DateTime.Now;
                                //await _scGetWMSTaskService.InsertTaskRouteDetailRecordInfoAsync(taskRouteDetailRecordInfo);

                                #region 堆垛机下架成功，更改出库台的值
                                //SCModel model = new() { 
                                //    SCCode = scEquipmentDbObject.EquipmentCode.ToUpper().Trim(),
                                //    SCDownState =1
                                //};
                                //SC_Manager.sc_list.Add(model);
                                #endregion

                                //runLogInfo.RunLog = $"插入到任务路径详细记录表";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                            else
                            {
                                runLogInfo.RunLog = $"堆垛机任务执行完成，WCS写入PLC失败！";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                _logUtil.Error(runLogInfo.RunLog);
                            }

                            stopwatch.Stop();
                            if (_logUtil.LogOpen == "1")
                            {
                                var JobOrderCode = wcsSendPlc.Jobordercode == 2 ? "出库" : "越库";
                                _logUtil.Debug($"获取{zJNScMessagePlcActionBO?.EquipmentCode}下发任务完成|{JobOrderCode}|{stopwatch.ElapsedMilliseconds}");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        runLogInfo.RunLog = $"托盘【{palletCodeCurrent}】出入库任务异常{ex.Message}";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        //_logUtil.Error(runLogInfo.RunLog);
                        _logUtil.Error($"托盘【{palletCodeCurrent}】出入库任务异常{ex.StackTrace}");
                    }


                }

                #endregion

                #region  入库任务申请校验
                if (zJNScMessagePlcActionBO.StackerHandAutomatic &&
                     !zJNScMessagePlcActionBO.StackerBusy &&
                    !zJNScMessagePlcActionBO.StackerAlarm &&
                    !zJNScMessagePlcActionBO.Stackerrunningsignal &&
                    //zJNScMessagePlcActionBO.SecurityDooronLine && //TODO 68项目暂时安全门默认打开所以先移除安全门判断
                    !zJNScMessagePlcActionBO.Forkhasaterial &&
                    !zJNScMessageWcsActionBO.Startcommand&&
                    zJNScMessagePlcActionBO.yuliu_1 == 888)//申请取料校验
                {
                    var CurrentjobnumberNow = "";
                    try
                    {
                        //获取Sc写入Db
                        PlcWriteDbInfo plcWriteDbInfo = await _scGetWMSTaskService.ScGetPlcWriteDbInfoAsync(zJNScMessagePlcActionBO.EquipmentCode,
                            "ZJNScMessageWriteWcsActionBO");
                        //Sc使用Plc连接
                        var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);
                        if (plcservice == null)
                        {
                            runLogInfo.RunLog = $"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            return;
                        }
                        //1. 验证plc是否在线
                        var plcIPStates = await _IPlcConnectionStateInfoRepository.GetFirstAsync(l => l.PlcConnectionID == zJNScMessagePlcActionBO.PlcConnectionID && l.Connected == true);
                        if (plcIPStates == null)
                        {
                            runLogInfo.RunLog = "plc已离线";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            return;
                        }

                        //组织报文，先默认当前报文内容
                        ZJNScMessageWriteWcsActionBO wcsSendPlcCheck = new ZJNScMessageWriteWcsActionBO();
                        wcsSendPlcCheck.Startcommand = zJNScMessageWcsActionBO.Startcommand;
                        wcsSendPlcCheck.Alarmreset = zJNScMessageWcsActionBO.Alarmreset;
                        wcsSendPlcCheck.Taskreset = zJNScMessageWcsActionBO.Taskreset;
                        wcsSendPlcCheck.WCSfirecommand = zJNScMessageWcsActionBO.WCSfirecommand;
                        wcsSendPlcCheck.WCSPhotoFire = zJNScMessageWcsActionBO.WCSPhotoFire;
                        wcsSendPlcCheck.WCSRgvFireHlper = zJNScMessageWcsActionBO.WCSRgvFireHlper;
                        wcsSendPlcCheck.WCSDTSAlarm = zJNScMessageWcsActionBO.WCSDTSAlarm;
                        wcsSendPlcCheck.TimeReset = zJNScMessageWcsActionBO.TimeReset;
                        wcsSendPlcCheck.Jobnumber = zJNScMessageWcsActionBO.Jobnumber;
                        wcsSendPlcCheck.Jobordercode = zJNScMessageWcsActionBO.Jobordercode;
                        wcsSendPlcCheck.StartlinefromPC = zJNScMessageWcsActionBO.StartlinefromPC;
                        wcsSendPlcCheck.StartcolumnfromPC = zJNScMessageWcsActionBO.StartcolumnfromPC;
                        wcsSendPlcCheck.StartlayerfromPC = zJNScMessageWcsActionBO.StartlayerfromPC;
                        wcsSendPlcCheck.TargetlinefromPC = zJNScMessageWcsActionBO.TargetlinefromPC;
                        wcsSendPlcCheck.TargetcolumnfromPC = zJNScMessageWcsActionBO.TargetcolumnfromPC;
                        wcsSendPlcCheck.TargetlayerfromPC = zJNScMessageWcsActionBO.TargetlayerfromPC;
                        wcsSendPlcCheck.WCSpostingcompleted = zJNScMessageWcsActionBO.WCSpostingcompleted;
                        wcsSendPlcCheck.yuliu8 = zJNScMessageWcsActionBO.yuliu8;
                        wcsSendPlcCheck.yuliu9 = zJNScMessageWcsActionBO.yuliu9;
                        wcsSendPlcCheck.yuliu10 = zJNScMessageWcsActionBO.yuliu10;
                        wcsSendPlcCheck.yuliu11 = zJNScMessageWcsActionBO.yuliu11;
                        wcsSendPlcCheck.yuliu12 = zJNScMessageWcsActionBO.yuliu12;
                        CurrentjobnumberNow = zJNScMessagePlcActionBO.Currentjobnumber.ToString();
                        //通过堆垛机报文的任务号 获取堆垛机当前任务的详情
                        var wmsTaskEx = await _scGetWMSTaskService.ScGetWorkTaskInfoByWcsTaskCodeAsync(zJNScMessagePlcActionBO.Currentjobnumber);
                        if (wmsTaskEx == null)
                        {
                            runLogInfo.RunLog = $"堆垛机当前入库任务【{zJNScMessagePlcActionBO.Currentjobnumber}】状态有误！请检查任务！";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            wcsSendPlcCheck.yuliu9 = 333;
                            byte[] wcsCheckBytess = wcsSendPlcCheck.Deserialize();
                            bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsCheckBytess);//写入PLC
                            if (flag)
                            {
                                _logUtil.Error($"入库台叉料校验失败【{zJNScMessagePlcActionBO.Currentjobnumber}】，写入报文成功！");
                            }
                            return;
                        }
                        //获取该任务的入库台报文
                        PlanarStateBO puStationBo = planarStateBOs.Find(it => it.EquipmentCode.ToString() == wmsTaskEx.CurrentFromEquipment);
                        if (puStationBo == null)
                        {
                            runLogInfo.RunLog = $"入库台{wmsTaskEx.CurrentFromEquipment} 没有配置交接台信息";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            wcsSendPlcCheck.yuliu9 = 333;
                            byte[] wcsCheckBytess = wcsSendPlcCheck.Deserialize();
                            bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsCheckBytess);//写入PLC
                            if (flag)
                            {
                                _logUtil.Error($"入库台叉料校验失败入库台报文获取失败【{zJNScMessagePlcActionBO.Currentjobnumber}】，写入报文成功！");
                            }
                            return;
                        }
                        if (puStationBo.TaskCode != wmsTaskEx.TaskCode)
                        {
                            runLogInfo.RunLog = $"堆垛机当前入库任务【{zJNScMessagePlcActionBO.Currentjobnumber}】与入库台任务【{puStationBo.TaskCode}】不一致！请检查任务！";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            wcsSendPlcCheck.yuliu9 = 333;
                            byte[] wcsCheckBytess = wcsSendPlcCheck.Deserialize();
                            bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsCheckBytess);//写入PLC
                            if (flag)
                            {
                                _logUtil.Error($"入库台叉料校验失败【{zJNScMessagePlcActionBO.Currentjobnumber}】，写入报文成功！");
                            }
                        }
                        else
                        {
                            wcsSendPlcCheck.yuliu9 = 666;
                            byte[] wcsCheckBytess = wcsSendPlcCheck.Deserialize();
                            bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsCheckBytess);//写入PLC
                            if (flag)
                            {
                                _logUtil.Error($"入库台叉料校验成功！【{zJNScMessagePlcActionBO.Currentjobnumber}】，写入报文成功！");
                            }
                        }
                        return;
                    }
                    catch (Exception ex)
                    {
                        runLogInfo.RunLog = $"堆垛机任务号【{CurrentjobnumberNow}】校验入库台任务异常{ex.Message}";
                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    }
                }

                #endregion


                #region SC卸载任务完成
                if (_logUtil.LogOpen == "2")
                {
                    _logUtil.Debug($"{zJNScMessagePlcActionBO?.EquipmentCode}SC卸载任务完成(TRUE,FALSE)|堆垛机运行信号{zJNScMessagePlcActionBO.Stackerrunningsignal}|自动任务复位{zJNScMessageWcsActionBO.Taskreset}");
                }
                if (zJNScMessagePlcActionBO.StackerHandAutomatic &&
                    !zJNScMessagePlcActionBO.StackerAlarm &&
                    zJNScMessagePlcActionBO.Stackerrunningsignal &&
                    //zJNScMessagePlcActionBO.SecurityDooronLine &&
                    zJNScMessagePlcActionBO.StackerTaskCompletion &&
                    !zJNScMessageWcsActionBO.Taskreset)
                {
                    try
                    {
                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        if (_logUtil.LogOpen == "1")
                        {
                            _logUtil.Debug($"获取{zJNScMessagePlcActionBO?.EquipmentCode}卸载任务开始{zJNScMessagePlcActionBO.Currentjobnumber}");
                        }
                        runLogInfo.RunType = "堆垛机下料任务完成业务";
                        runLogInfo.RunLog = $"堆垛机任务号【{zJNScMessagePlcActionBO.Currentjobnumber}】PLC上报通知WCS完成！WCS开始处理业务";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        _logUtil.Info(runLogInfo.RunLog);
                        var wmstask = await _scGetWMSTaskService.ScGetWorkTaskInfoByWcsTaskCodeAsync(zJNScMessagePlcActionBO.Currentjobnumber);
                        if (wmstask == null)
                        {
                            runLogInfo.RunLog = $"SC编号{zJNScMessagePlcActionBO.EquipmentCode} 作业号{zJNScMessagePlcActionBO.Currentjobnumber} 没有WCS作业";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            _logUtil.Error(runLogInfo.RunLog);

                            #region 同一任务重复申请
                            ZJNScMessageWriteWcsActionBO wcsSendPlc1 = new ZJNScMessageWriteWcsActionBO();
                            wcsSendPlc1.Startcommand = zJNScMessageWcsActionBO.Startcommand;
                            wcsSendPlc1.Alarmreset = zJNScMessageWcsActionBO.Alarmreset;
                            wcsSendPlc1.Taskreset = true;
                            wcsSendPlc1.WCSfirecommand = zJNScMessageWcsActionBO.WCSfirecommand;

                            wcsSendPlc1.WCSPhotoFire = false;
                            wcsSendPlc1.WCSRgvFireHlper = false;
                            wcsSendPlc1.WCSDTSAlarm = false;
                            wcsSendPlc1.TimeReset = false;

                            wcsSendPlc1.Jobnumber = zJNScMessageWcsActionBO.Jobnumber;
                            wcsSendPlc1.Jobordercode = zJNScMessageWcsActionBO.Jobordercode;
                            wcsSendPlc1.StartlinefromPC = zJNScMessageWcsActionBO.StartlinefromPC;
                            wcsSendPlc1.StartcolumnfromPC = zJNScMessageWcsActionBO.StartcolumnfromPC;
                            wcsSendPlc1.StartlayerfromPC = zJNScMessageWcsActionBO.StartlayerfromPC;
                            wcsSendPlc1.TargetlinefromPC = zJNScMessageWcsActionBO.TargetlinefromPC;
                            wcsSendPlc1.TargetcolumnfromPC = zJNScMessageWcsActionBO.TargetcolumnfromPC;
                            wcsSendPlc1.TargetlayerfromPC = zJNScMessageWcsActionBO.TargetlayerfromPC;
                            wcsSendPlc1.WCSpostingcompleted = zJNScMessageWcsActionBO.WCSpostingcompleted;
                            wcsSendPlc1.yuliu8 = zJNScMessageWcsActionBO.yuliu8;
                            wcsSendPlc1.yuliu9 = 0;
                            wcsSendPlc1.yuliu10 = 0;
                            wcsSendPlc1.yuliu11 = 0;
                            wcsSendPlc1.yuliu12 = 0;
                            byte[] wcsBytes1 = wcsSendPlc1.Deserialize();
                            //获取Sc写入Db
                            PlcWriteDbInfo plcWriteDbInfo1 = await _scGetWMSTaskService.ScGetPlcWriteDbInfoAsync(zJNScMessagePlcActionBO.EquipmentCode, "ZJNScMessageWriteWcsActionBO");
                            //Sc使用Plc连接
                            var plcservice1 = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo1.PlcConnectionId);
                            if (plcservice1 == null)
                            {
                                runLogInfo.RunLog = $"PLC连接Id:{plcWriteDbInfo1.PlcConnectionId}不存在";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                _logUtil.Error(runLogInfo.RunLog);
                            }
                            var plcIPStates1 = await _IPlcConnectionStateInfoRepository.GetFirstAsync(l => l.PlcConnectionID == zJNScMessagePlcActionBO.PlcConnectionID && l.Connected == true);
                            if (plcIPStates1 == null)
                            {
                                runLogInfo.RunLog = $"{plcservice1.IP}plc已离线";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                _logUtil.Error(runLogInfo.RunLog);
                                return;
                            }

                            await plcservice1.WriteDbToSCAsync(plcWriteDbInfo1.DbCode, plcWriteDbInfo1.DbStart, wcsBytes1);
                            #endregion
                        }

                        var routedetail = await _scGetWMSTaskService.GetRouteDetailInfoByIdAsync(wmstask.CurrentRounteDetailID);


                        ZJNScMessageWriteWcsActionBO wcsSendPlc = new ZJNScMessageWriteWcsActionBO();
                        wcsSendPlc.Startcommand = zJNScMessageWcsActionBO.Startcommand;
                        wcsSendPlc.Alarmreset = zJNScMessageWcsActionBO.Alarmreset;
                        wcsSendPlc.Taskreset = true;
                        wcsSendPlc.WCSfirecommand = zJNScMessageWcsActionBO.WCSfirecommand;

                        wcsSendPlc.WCSPhotoFire = false;
                        wcsSendPlc.WCSRgvFireHlper = false;
                        wcsSendPlc.WCSDTSAlarm = false;
                        wcsSendPlc.TimeReset = false;

                        wcsSendPlc.Jobnumber = zJNScMessageWcsActionBO.Jobnumber;
                        wcsSendPlc.Jobordercode = zJNScMessageWcsActionBO.Jobordercode;
                        wcsSendPlc.StartlinefromPC = zJNScMessageWcsActionBO.StartlinefromPC;
                        wcsSendPlc.StartcolumnfromPC = zJNScMessageWcsActionBO.StartcolumnfromPC;
                        wcsSendPlc.StartlayerfromPC = zJNScMessageWcsActionBO.StartlayerfromPC;
                        wcsSendPlc.TargetlinefromPC = zJNScMessageWcsActionBO.TargetlinefromPC;
                        wcsSendPlc.TargetcolumnfromPC = zJNScMessageWcsActionBO.TargetcolumnfromPC;
                        wcsSendPlc.TargetlayerfromPC = zJNScMessageWcsActionBO.TargetlayerfromPC;
                        wcsSendPlc.WCSpostingcompleted = zJNScMessageWcsActionBO.WCSpostingcompleted;
                        wcsSendPlc.yuliu8 = zJNScMessageWcsActionBO.yuliu8;
                        wcsSendPlc.yuliu9 = 0;
                        wcsSendPlc.yuliu10 = 0;
                        wcsSendPlc.yuliu11 = 0;
                        wcsSendPlc.yuliu12 = 0;
                        byte[] wcsBytes = wcsSendPlc.Deserialize();
                        //获取Sc写入Db
                        PlcWriteDbInfo plcWriteDbInfo = await _scGetWMSTaskService.ScGetPlcWriteDbInfoAsync(zJNScMessagePlcActionBO.EquipmentCode, "ZJNScMessageWriteWcsActionBO");
                        //Sc使用Plc连接
                        var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);
                        if (plcservice == null)
                        {
                            runLogInfo.RunLog = $"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            _logUtil.Error(runLogInfo.RunLog);
                        }
                        var plcIPStates = await _IPlcConnectionStateInfoRepository.GetFirstAsync(l => l.PlcConnectionID == zJNScMessagePlcActionBO.PlcConnectionID && l.Connected == true);
                        if (plcIPStates == null)
                        {
                            runLogInfo.RunLog = $"{plcservice.IP}plc已离线";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            _logUtil.Error(runLogInfo.RunLog);
                            return;
                        }
                        if (routedetail.IsEnd)
                        {
                            bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsBytes);
                            if (flag)
                            {
                                runLogInfo.RunLog = $"堆垛机业务：堆垛入库放料完成回复堆垛机【{plcWriteDbInfo.EquipmentCode}】ip:【{plcservice.IP}】写入成功报文内容：{JsonConvert.SerializeObject(wcsSendPlc)}";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                wmstask.TaskProcessState = EnumTaskProcessState.ScUnloaded;
                                wmstask.CurrentDetailTaskState = EnumDetailTaskState.Finish;
                                wmstask.CurrentUpdateTime = DateTime.Now;
                                wmstask.TaskState = EnumTaskState.Finish;
                                wmstask.UpdateTime = DateTime.Now;
                                WMSApiDomain.WebApi.HeaderResult<bool> send = new();
                                try
                                {
                                    send = await WCSMessageWithWMSApi.WCSNoticeTaskAutoCompleteAsync(wmstask.WmsTaskCode, wmstask.PalletCode, wmstask.WmsToPosition);
                                }
                                catch (Exception ex)
                                {
                                    //runLogInfo.RunLog = $"{wmstask.WmsTaskCode} 上报WMS消息异常" + ex.ToString();
                                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                    _logUtil.Error($"堆垛机业务：托盘【{wmstask.PalletCode}】堆垛入库放料完成任务号【{wmstask.WmsTaskCode}】 上报WMS消息异常" + ex.ToString());
                                }
                                if (send.IsSucceed)
                                {
                                    wmstask.UploadWmsState = EnumUploadWmsState.Succeed;

                                    runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】堆垛入库放料完成任务号【{wmstask.WmsTaskCode}】 上报WMS成功";
                                }
                                else
                                {
                                    runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】堆垛入库放料完成任务号【{wmstask.WmsTaskCode}】 上报WMS失败;WMS回应：{send.Message}";
                                    //runLogInfo.RunLog = $"{wmstask.WmsTaskCode} 上报WMS失败;WMS回应{send.Message}";
                                    wmstask.UploadWmsState = EnumUploadWmsState.Failed;
                                }
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                wmstask.UploadWmsTime = DateTime.Now;
                                //更新wcs任务
                                await _scGetWMSTaskService.ScUpdateWorkTaskInfoAsync(wmstask);

                                runLogInfo.RunLog = $"堆垛机业务：堆垛机卸载托盘【{wmstask.PalletCode}】任务【{zJNScMessagePlcActionBO.Currentjobnumber}】处理完成！托盘放入库位完成！";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                
                            }
                        }
                        else
                        {
                            TaskRouteDetailRecordInfo taskRouteDetailRecordInfo = new TaskRouteDetailRecordInfo();
                            taskRouteDetailRecordInfo.TaskID = wmstask.ID;
                            taskRouteDetailRecordInfo.RouteDetailID = routedetail.ID;
                            taskRouteDetailRecordInfo.DetailTaskState = EnumDetailTaskState.Finish;
                            taskRouteDetailRecordInfo.DispatchType = routedetail.DispatchType;
                            taskRouteDetailRecordInfo.FromEquipment = routedetail.FromEquipment;
                            taskRouteDetailRecordInfo.FromCargo = routedetail.FromCargo;
                            taskRouteDetailRecordInfo.ToEquipment = routedetail.ToEquipment;
                            taskRouteDetailRecordInfo.ToCargo = routedetail.ToCargo;
                            taskRouteDetailRecordInfo.CreateTime = wmstask.CurrentCreateTime;
                            taskRouteDetailRecordInfo.UpdateTime = DateTime.Now;

                            var nextroutedetail = await _scGetWMSTaskService.GetNextRouteDetailInfoByIdAsync(wmstask.CurrentRounteDetailID);
                            wmstask.TaskProcessState = EnumTaskProcessState.ScUnloaded;
                            wmstask.CurrentRounteDetailID = nextroutedetail.ID;
                            wmstask.CurrentDetailTaskState = EnumDetailTaskState.Init;
                            wmstask.CurrentDispatchType = nextroutedetail.DispatchType;
                            wmstask.CurrentFromEquipment = nextroutedetail.FromEquipment;
                            wmstask.CurrentFromCargo = nextroutedetail.FromCargo;
                            wmstask.CurrentToEquipment = nextroutedetail.ToEquipment;
                            wmstask.CurrentToCargo = nextroutedetail.ToCargo;
                            wmstask.CurrentCreateTime = DateTime.Now;
                            wmstask.CurrentUpdateTime = new DateTime(1900, 1, 1);

                            //TODO20230611修改逻辑
                            // 1、优先写入报文到出库台
                            // 2、出库台写入成功后写堆垛机自动复位报文
                            // 3、更新wcs任务节点
                            // 4、调用wms到达DO台接口释放货位

                            #region 处理到达出库台业务
                            //向出库台写入托盘信息以及任务信息
                            //获取出库台报文
                            PlanarStateBO dostation = planarStateBOs.Find(it => it.EquipmentCode.ToString() == wmstask.CurrentFromEquipment);
                            if (dostation == null)
                            {
                                runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，出库台【{wmstask.CurrentFromEquipment}】读取失败，检查PLC设备号或者出库台DB设置！";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                return;
                            }
                            ////3. 验证wcs任务，验证wcs当前子任务
                            //var exp = Expressionable.Create<WorkTaskInfo>();
                            //exp.AndIF(true, it => it.CurrentFromEquipment == dostation.EquipmentCode && it.TaskState == EnumTaskState.Executing && it.CurrentDetailTaskState == EnumDetailTaskState.Init &&
                            //it.TaskProcessState == EnumTaskProcessState.ScUnloaded);
                            //var task = await _WorkTaskInfoRepository.GetFirstAsync(exp.ToExpression());

                            //4. 组织报文，写入plc
                            //获取出库台写db配置
                            var objectType = typeof(PlanarGeneralWriteWcsAction).Name;
                            var writeConfig = await _plcWriteDbInfoRepository.GetFirstAsync(it => it.EquipmentCode == dostation.EquipmentCode && it.ObjectType == objectType);
                            if (writeConfig == null)
                            {
                                //runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息获取出库台【{dostation.EquipmentCode}】写入配置失败,请检查是否配置！";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                _logUtil.Error($"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息获取出库台【{dostation.EquipmentCode}】写入配置失败,请检查是否配置！");
                                return;
                            }

                            //if (task == null)
                            //{
                            //    //runLogInfo.RunLog = $"堆垛机业务：托盘【{task.PalletCode}】处理出库台信息，任务号【{task.TaskCode}】堆垛机未报完成或者未正确处理完成业务！";
                            //    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            //    _logUtil.Error($"堆垛机业务：托盘【{task.PalletCode}】处理出库台信息，任务号【{task.TaskCode}】堆垛机未报完成或者未正确处理完成业务！");
                            //    //var res = await plcConn.WriteDbAsync(writeAlrmBo.DbCode, writeAlrmBo.DbStart, writeAlrmBo.Deserialize());
                            //    return;
                            //}

                            //if (task.CurrentDetailTaskState == EnumDetailTaskState.Finish)
                            //{
                            //    runLogInfo.RunLog = $"堆垛机业务：托盘【{task.PalletCode}】处理出库台信息，任务号【{task.TaskCode}】已完成，无需操作！请检查该任务";
                            //    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            //    return;
                            //}


                            //获取任务的路径信息
                            var routeConfigExp = Expressionable.Create<RouteInfo>();
                            routeConfigExp.AndIF(true, (a) => a.FromStation == wmstask.WmsFromStation && a.ToStation == wmstask.WmsToStation);
                            var routeInfo = await _WorkTaskInfoRepository.AsSugarClient()
                                .Queryable<RouteInfo>()
                                .Where(routeConfigExp.ToExpression())
                                .Select((a) => new RouteInfo()
                                {
                                    ID = a.ID,
                                    FromStation = a.FromStation,
                                    ToStation = a.ToStation,
                                }).FirstAsync();
                            if (routeInfo == null)
                            {
                                //runLogInfo.RunLog = $"堆垛机业务：托盘【{task.PalletCode}】处理出库台信息，任务号【{task.TaskCode}】起始工位{task.WmsFromStation}目标工位{task.WmsToStation}获取失败，请检查路径配置！";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                _logUtil.Error($"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】起始工位{wmstask.WmsFromStation}目标工位{wmstask.WmsToStation}获取失败，请检查路径配置！");
                                //var res = await plcConn.WriteDbAsync(writeAlrmBo.DbCode, writeAlrmBo.DbStart, writeAlrmBo.Deserialize());
                                return;
                            }

                            //路径详情信息获取
                            var routeDetailConfigExp = Expressionable.Create<RouteDetailInfo>();
                            routeDetailConfigExp.AndIF(true, (a) => a.RouteID == routeInfo.ID && a.IsEnd);
                            var routeDetailInfo = await _WorkTaskInfoRepository.AsSugarClient()
                                .Queryable<RouteDetailInfo>()
                                .Where(routeDetailConfigExp.ToExpression())
                                .Select((a) => new
                                {
                                    ID = a.ID,
                                    RouteID = a.RouteID,
                                    //FromCargo = a.FromCargo,
                                    //ToCargo = a.ToCargo,
                                    //DispatchType = a.DispatchType,
                                    //FromEquipment = a.FromEquipment,
                                    ToEquipment = a.ToEquipment,

                                }).FirstAsync();


                            PlanarGeneralWriteWcsAction planarWriteBo = new PlanarGeneralWriteWcsAction(
                                writeConfig.PlcConnectionId,
                                writeConfig.ID,
                                writeConfig.DbCode,
                                writeConfig.DbStart,
                                objectType,
                                dostation.EquipmentCode.ToInt32(),
                                0,//plcMessage.ActionType
                                routeDetailInfo.ToEquipment.ToInt32(), //plcMessage.ToEquipmentCode,
                                wmstask.TaskCode, //plcMessage.TaskCode,
                                wmstask.PalletCode, //plcMessage.PalletBarcode,
                                0,
                                0); //预留4
                            //托盘类型
                            switch (wmstask.PalletCode.Substring(1, 1))
                            {
                                case "A":
                                    planarWriteBo.PalletType = 2;
                                    break;
                                case "B":
                                    planarWriteBo.PalletType = 1;
                                    break;
                                case "C":
                                    planarWriteBo.PalletType = 3;
                                    break;
                            }
                            //回复PLC 写入报文
                            planarWriteBo.ActionType = dostation.ActionType;
                            PlcConnectionS7 plcConnDo = _plcConnectionPool.S7GetWritePlcConnection(writeConfig.PlcConnectionId);//plc写入连接（不锁定）
                            if (plcConnDo == null || !plcConnDo.IsConnected)
                            {
                                //runLogInfo.RunLog = $"获取DO台PLC连接失败，或者未连接PLCID【{writeConfig.PlcConnectionId}】DO台设备号：{dostation.EquipmentCode}";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                _logUtil.Error($"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】PLCIP【{plcConnDo.IP}】设备【{dostation.EquipmentCode}】获取连接失败！");
                                return;
                            }
                            //写入出库台报文
                            var writeResult = await plcConnDo.WriteDbAsync(planarWriteBo.DbCode, planarWriteBo.DbStart, planarWriteBo.Deserialize());

                            if (writeResult == false)//写入失败！
                            {
                                //runLogInfo.RunLog = $"PLC(IP{plcConnDo.IP})写入报文失败";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                _logUtil.Error($"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】PLCIP【{plcConnDo.IP}】设备【{dostation.EquipmentCode}】写入失败报文内容： {JsonConvert.SerializeObject(planarWriteBo)}");
                                return;
                            }
                            else//出库台报文写入成功
                            {
                                runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】PLCIP【{plcConnDo.IP}】设备【{dostation.EquipmentCode}】写入成功报文内容： {JsonConvert.SerializeObject(planarWriteBo)}";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                //写入堆垛机自动复位报文
                                bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsBytes);
                                if (flag)
                                {
                                    runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】堆垛出库放料完成任务号【{wmstask.WmsTaskCode}】ip:【{plcservice.IP}】写入成功报文内容：{JsonConvert.SerializeObject(wcsSendPlc)}";
                                    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);

                                    wmstask.CurrentToEquipment = routeDetailInfo.ToEquipment.ToString();
                                    wmstask.CurrentDetailTaskState = EnumDetailTaskState.Executing;
                                    wmstask.UpdateTime = DateTime.Now;
                                    //更新wcs任务
                                    var isUpdateRes = await _scGetWMSTaskService.ScUpdateWorkTaskInfoRouteDetailAsync(wmstask);//更新到任务
                                    if (isUpdateRes)
                                    {
                                        runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】堆垛出库放料完成任务号【{zJNScMessagePlcActionBO.Currentjobnumber}】放料更新完成！已切换未下一路径任务！";
                                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                        //调用wms到达DO台接口释放货位
                                        WMSApiDomain.WebApi.HeaderResult<bool> result = await WCSMessageWithWMSApi.WCSNoticePalltetArriveDoEquipmentAsync(wmstask.WmsTaskCode);
                                        if (result.IsSucceed)
                                        {
                                            runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】WMS释放货位成功";
                                        }
                                        else
                                        {
                                            //runLogInfo.RunLog = $"堆垛机业务：托盘【{task.PalletCode}】处理出库台信息，任务号【{task.TaskCode}】WMS释放货位失败报错：{result.Message}";
                                            _logUtil.Error($"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】WMS释放货位失败报错：{result.Message}");
                                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                            return;
                                        }
                                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);

                                    }
                                    else
                                    {
                                        //runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】堆垛机已报完成但是系统上报WMS更新失败！";
                                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                        _logUtil.Error($"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】堆垛机已报完成但是系统上报WMS更新失败！");
                                        return;
                                    }
                                }
                            }

                            //task.CurrentToEquipment = routeDetailInfo.ToEquipment.ToString();
                            //task.CurrentDetailTaskState = EnumDetailTaskState.Executing;
                            //task.UpdateTime = DateTime.Now;
                            //await _WorkTaskInfoRepository.UpdateAsync(task);
                            //runLogInfo.RunLog = $"堆垛机业务：托盘【{wmstask.PalletCode}】处理出库台信息，任务号【{wmstask.TaskCode}】到达DO处理成功";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            runLogInfo.RunLog = $"堆垛机业务：堆垛机卸载托盘【{wmstask.PalletCode}】任务【{zJNScMessagePlcActionBO.Currentjobnumber}】处理完成！到达出库台完成！";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            #endregion
                        }

                        stopwatch.Stop();
                        if (_logUtil.LogOpen == "1")
                        {
                            _logUtil.Debug($"获取{zJNScMessagePlcActionBO?.EquipmentCode}卸载任务完成{zJNScMessagePlcActionBO.Currentjobnumber}|{wmstask.CurrentDispatchType}|{stopwatch.ElapsedMilliseconds}");
                        }
                    }
                    catch (Exception ex)
                    {
                        //runLogInfo.RunLog = $"卸载任务异常{ex.Message}";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        _logUtil.Error($"堆垛机业务：任务【{zJNScMessagePlcActionBO.Currentjobnumber}】卸载任务异常{ex}");
                    }
                }
                #endregion

                #region SC重入上报
                if (zJNScMessagePlcActionBO.ReEntery && zJNScMessagePlcActionBO.Stackeralarmcode == 3 &&
                    zJNScMessagePlcActionBO.Forkhasaterial)
                {
                    try
                    {
                        var reenter = await _scGetWMSTaskService.ScGetReEnterWorkTaskInfoAsync(zJNScMessagePlcActionBO.Currentjobnumber);
                        if (reenter == null)
                        {
                            throw new Exception($"{zJNScMessagePlcActionBO.EquipmentCode} 在重入报警中,WMS在分配新货位");
                        }
                        AllotLocationOutputDto allotLocationOutputDto = null;
                        try
                        {
                            allotLocationOutputDto = await WCSMessageWithWMSApi.WCSGetReAllotLocatonAsync(reenter.WmsTaskCode, reenter.WmsToPosition);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception($"{zJNScMessagePlcActionBO.EquipmentCode}货位重分配异常" + ex.ToString());
                        }
                        reenter.WmsToPosition = allotLocationOutputDto.LocationCode;
                        reenter.TaskProcessState = EnumTaskProcessState.ReAllotLocation;
                        reenter.UpdateTime = DateTime.Now;
                        reenter.CurrentToCargo = allotLocationOutputDto.LocationCode;
                        reenter.CurrentUpdateTime = DateTime.Now;
                        await _scGetWMSTaskService.WcsUpdateReallotLocationAsync(reenter);
                    }
                    catch (Exception ex)
                    {
                        _logUtil.Info(ex.ToString());
                    }
                }
                #endregion

                #region  WCS下发SC重入作业
                if (zJNScMessagePlcActionBO.StackerHandAutomatic &&//自动状态
                   zJNScMessagePlcActionBO.StackerBusy &&//空闲状态
                  !zJNScMessagePlcActionBO.StackerAlarm &&//无报警
                   zJNScMessagePlcActionBO.SecurityDooronLine &&//安全门正常
                   zJNScMessagePlcActionBO.Forkhasaterial &&//有料
                  !zJNScMessageWcsActionBO.Startcommand)//未启动
                {
                    try
                    {
                        var wmsReallotLocationTask = await _scGetWMSTaskService.ScGetReallotLocationByScEquipmentAsync(zJNScMessagePlcActionBO.EquipmentCode);
                        if (wmsReallotLocationTask == null)
                        {
                            throw new Exception($"{zJNScMessagePlcActionBO.EquipmentCode} 没有查询到重新分配的作业");
                        }

                        //获取Sc写入Db
                        PlcWriteDbInfo plcWriteDbInfo = await _scGetWMSTaskService.ScGetPlcWriteDbInfoAsync(zJNScMessagePlcActionBO.EquipmentCode, "ZJNScMessageWriteWcsActionBO");
                        //Sc使用Plc连接
                        var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);
                        if (plcservice == null)
                        {
                            throw new Exception($"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在");
                        }
                        var plcIPStates = await _IPlcConnectionStateInfoRepository.GetFirstAsync(l => l.PlcConnectionID == zJNScMessagePlcActionBO.PlcConnectionID && l.Connected == true);
                        if (plcIPStates == null)
                        {
                            _logUtil.Info($"SC卸载任务完成处理失败：设备编号{zJNScMessagePlcActionBO.EquipmentCode}{plcservice.IP}plc已离线");
                            return;
                        }
                        ZJNScMessageWriteWcsActionBO wcsSendPlc = new ZJNScMessageWriteWcsActionBO();
                        wcsSendPlc.Startcommand = true;
                        wcsSendPlc.Alarmreset = true;
                        wcsSendPlc.Taskreset = false;
                        wcsSendPlc.WCSfirecommand = false;
                        wcsSendPlc.WCSPhotoFire = false;
                        wcsSendPlc.WCSRgvFireHlper = false;
                        wcsSendPlc.WCSDTSAlarm = false;
                        wcsSendPlc.TimeReset = false;
                        wcsSendPlc.Jobnumber = wmsReallotLocationTask.TaskCode;

                        if (wmsReallotLocationTask.CurrentDispatchType == EnumDispatchType.SC_UP) //入库
                        {
                            wcsSendPlc.Jobordercode = 1;

                        }
                        else if (wmsReallotLocationTask.CurrentDispatchType == EnumDispatchType.SC_MOVE) //巷道内移动
                        {
                            wcsSendPlc.Jobordercode = 3;
                        }
                        wcsSendPlc.StartlinefromPC = Convert.ToInt16(wmsReallotLocationTask.CurrentFromCargo.Substring(1, 3)) % 2 == 1 ? (short)1 : (short)2;
                        wcsSendPlc.StartcolumnfromPC = Convert.ToInt16(wmsReallotLocationTask.CurrentFromCargo.Substring(4, 3));
                        wcsSendPlc.StartlayerfromPC = Convert.ToInt16(wmsReallotLocationTask.CurrentFromCargo.Substring(7, 3));
                        wcsSendPlc.TargetlinefromPC = Convert.ToInt16(wmsReallotLocationTask.CurrentToCargo.Substring(1, 3)) % 2 == 1 ? (short)1 : (short)2;
                        wcsSendPlc.TargetcolumnfromPC = Convert.ToInt16(wmsReallotLocationTask.CurrentToCargo.Substring(4, 3));
                        wcsSendPlc.TargetlayerfromPC = Convert.ToInt16(wmsReallotLocationTask.CurrentToCargo.Substring(7, 3));

                        wcsSendPlc.WCSpostingcompleted = 0;
                        wcsSendPlc.yuliu8 = 0;
                        wcsSendPlc.yuliu9 = 0;
                        wcsSendPlc.yuliu10 = 0;
                        wcsSendPlc.yuliu11 = 0;
                        wcsSendPlc.yuliu12 = 0;
                        byte[] wcsBytes = wcsSendPlc.Deserialize();
                        bool flag = await plcservice.WriteDbToSCAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, wcsBytes);//下发重入到PLC
                        if (flag)
                        {
                            TaskRouteDetailRecordInfo taskRouteDetailRecordInfo = new TaskRouteDetailRecordInfo();
                            taskRouteDetailRecordInfo.TaskID = wmsReallotLocationTask.ID;
                            taskRouteDetailRecordInfo.RouteDetailID = wmsReallotLocationTask.CurrentRounteDetailID;
                            taskRouteDetailRecordInfo.DetailTaskState = EnumDetailTaskState.Executing;
                            taskRouteDetailRecordInfo.DispatchType = wmsReallotLocationTask.CurrentDispatchType;
                            taskRouteDetailRecordInfo.FromEquipment = wmsReallotLocationTask.CurrentFromEquipment;
                            taskRouteDetailRecordInfo.FromCargo = wmsReallotLocationTask.CurrentFromCargo;
                            taskRouteDetailRecordInfo.ToEquipment = wmsReallotLocationTask.CurrentToEquipment;
                            taskRouteDetailRecordInfo.ToCargo = wmsReallotLocationTask.CurrentToCargo;
                            taskRouteDetailRecordInfo.CreateTime = wmsReallotLocationTask.CurrentCreateTime;
                            taskRouteDetailRecordInfo.UpdateTime = DateTime.Now;
                            await _scGetWMSTaskService.InsertTaskRouteDetailRecordInfoAsync(taskRouteDetailRecordInfo);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logUtil.Info($"WCS下发重入作业报错，ex= {ex.Message}");
                    }
                }
                #endregion

                #region  SC取空
                if (/*zJNScMessagePlcActionBO.TakeEmpty*/ zJNScMessagePlcActionBO.Stackeralarmcode == 2 &&
                 !zJNScMessagePlcActionBO.Forkhasaterial)
                {
                    try
                    {
                        var takeempty = await _scGetWMSTaskService.ScGetTakeEmptyWorkTaskInfoAsync(zJNScMessagePlcActionBO.Currentjobnumber);
                        if (takeempty == null)
                        {
                            throw new Exception($"{zJNScMessagePlcActionBO.EquipmentCode} 在取空报警中,WCS没有对应的作业");
                        }
                        takeempty.TaskState = EnumTaskState.Cancel;
                        takeempty.UpdateTime = DateTime.Now;
                        bool send = false;
                        try
                        {
                            send = await WCSMessageWithWMSApi.WCSNoticeErrorTaskProcessStateAsync(takeempty.WmsTaskCode, takeempty.WmsFromPosition, 5);
                        }
                        catch (Exception ex)
                        {
                            _logUtil.Info($"{takeempty.WmsTaskCode} 上报WMS消息异常," + ex.ToString());
                        }

                        if (send)
                        {
                            takeempty.UploadWmsState = EnumUploadWmsState.Succeed;
                        }
                        else
                        {
                            takeempty.UploadWmsState = EnumUploadWmsState.Failed;
                        }
                        await _scGetWMSTaskService.WcsUpdateTakeEmptyAsync(takeempty);
                    }
                    catch (Exception ex)
                    {
                        _logUtil.Info($"堆垛机取空上报报错，ex= {ex.Message}");
                    }
                }
                #endregion


                #region SC盘点作业
                /*
                1：当堆垛机自动放完成之后，PLC扫取托盘条码上报给WCS握手类型50，询问是否启动自动扫码，WCS恢复51为自动扫码，52为人工PDA扫码。
                2：自动扫码情况下，启动电芯扫码，将电芯条码传输到本地给WCS读取，PLC申请握手类型54，WCS回复55，（不管NG与否均拿堆垛机取走因此只需一种回复就OK）
                3：当堆垛机取料前判断到无料，上报给WCS握手类型56，询问是否自动清除当前任务，WCS回复57为自动清除，回复58为异常，堆垛机进行报警提示。
                */



                if (inventoryStateBO != null)
                {
                    #region 构建报文
                    //写入plc的报文配置获取
                    var objectType = typeof(PlanarInventoryWriteWcsAction).Name;
                    var writeConfig = await _plcWriteDbInfoRepository.GetFirstAsync(s => s.EquipmentCode == inventoryStateBO.EquipmentCode && s.ObjectType == objectType);
                    if (writeConfig == null)
                    {

                        runLogInfo.RunLog = "获取PLC写入配置失败";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        _logUtil.Error(runLogInfo.RunLog);
                        return;
                    }
                    //构建写入报文
                    writeBo = new PlanarInventoryWriteWcsAction(
                            writeConfig.PlcConnectionId,
                            writeConfig.ID,
                            writeConfig.DbCode,
                            writeConfig.DbStart,
                            objectType,
                            0
                            );

                    #endregion

                    ////TODO 用于测试
                    //if (inventoryStateBO.ActionType == 60)
                    //{
                    //    //51（自动）    
                    //    //回复plc是自动
                    //    writeBo.ActionType = 51;

                    //    var res = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    //    if (res)
                    //    {
                    //        runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，回复51自动扫码，写入报文成功";
                    //        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    //    }
                    //    else
                    //    {
                    //        runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，回复51自动扫码，写入报文失败";
                    //        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    //        return;
                    //    }
                    //}

                    InterfaceLogInfo interfaceLogInfo = new InterfaceLogInfo();

                    if (inventoryStateBO.ActionType == 50)
                    {
                        //PLC→WCS→WMS申请盘点模式    
                        WMSApiDomain.WebApi.HeaderResult<int> AutomaticOrManual = new WMSApiDomain.WebApi.HeaderResult<int>();
                        try
                        {
                            //调用WMS提供的接口，向WMS询问是自动扫码，还是人工PDA扫码，返回51表示自动（粗盘点），52人工（细盘点）;
                            AutomaticOrManual = await WCSMessageWithWMSApi.WCSGetCheckModelAsync(inventoryStateBO.PalletBarcode, inventoryStateBO.EquipmentCode);
                        }
                        catch (Exception ex)
                        {
                            _logUtil.Error($"调用WMS接口请求盘点模式失败，接口方法WCSGetCheckModelAsync,异常信息{ex.Message}");
                            return;
                        }

                        if (AutomaticOrManual.Result == 51)
                        {
                            //51（自动）    
                            //回复plc是自动
                            writeBo.ActionType = 51;

                            var res = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                            if (res)
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，回复51自动扫码，写入报文成功";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                            else
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，回复51自动扫码，写入报文失败";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                return;
                            }

                        }
                        else if (AutomaticOrManual.Result == 52)
                        {
                            //细盘点模式52（人工PDA扫码）
                            //回复plc是人工
                            writeBo.ActionType = 52;

                            var res = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                            if (res)
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，回复52人工PDA扫，写入报文成功";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                            else
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，回复52人工PDA扫，写入报文失败";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                return;
                            }


                        }

                    }



                    #region 电芯条码校验
                    if (inventoryStateBO.ActionType == 54)
                    {
                        //校验电芯
                        inventoryStateBO.PalletBarcode = inventoryStateBO.PalletBarcode.Trim();
                        inventoryStateBO.BatteryCode = inventoryStateBO.BatteryCode.Trim();
                        if (inventoryStateBO.BatteryCode.Length == 0 || inventoryStateBO.BatteryIndex == 0)
                        {
                            if (inventoryStateBO.BatteryCode.Length == 0)
                            {
                                runLogInfo.RunLog = $"字段BatteryCode：{inventoryStateBO.BatteryCode},电池条码为空";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                            if (inventoryStateBO.BatteryIndex == 0)
                            {
                                runLogInfo.RunLog = $"字段BatteryIndex：{inventoryStateBO.BatteryIndex},位置信息为0";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                        }
                        else
                        {
                            runLogInfo.RunLog = $"盘点校验电芯成功";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        }


                        writeBo.ActionType = 55;//WCS回复55，（不管NG与否均让堆垛机取走因此只需一种回复就OK）
                        if (inventoryStateBO.PalletBarcode == "ERROR" || inventoryStateBO.BatteryCode == "ERROR")
                        {
                            runLogInfo.RunLog = $"盘点扫码ERROR";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);

                            writeBo.ActionType = 66;//WCS回复66，plc扫码ERROR
                            var resbools66 = await plcConn.WriteDbAsync(writeConfig.DbCode, writeConfig.DbStart, writeBo.Deserialize());
                            if (resbools66)
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，盘点校验电芯，回复PLC握手类型66，写入报文成功";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                            else
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，盘点校验电芯，回复PLC握手类型66，写入报文失败";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                            return;
                        }

                        var resbools = await plcConn.WriteDbAsync(writeConfig.DbCode, writeConfig.DbStart, writeBo.Deserialize());
                        if (resbools)
                        {
                            runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，盘点校验电芯，回复PLC握手类型55，写入报文成功";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        }
                        else
                        {
                            runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，盘点校验电芯，回复PLC握手类型55，写入报文失败";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            //return;
                        }


                        /*向WMS上传数据
                         * 参数
                        containercode：plc扫码枪读出的托盘编码
                        plccode：协议里面的plc设备编号
                        batterycode:电芯条码
                        position：电芯位置
                        WMS产生任务给WCS----->WCS给到PLC(因为以前WMS下发WCS任务，WCS有拉取方法这里不在做返回结果处理)
                        */

                        WMSApiDomain.WebApi.HeaderResult<int> uploaddataResult = new WMSApiDomain.WebApi.HeaderResult<int>();

                        try
                        {
                            uploaddataResult = await WCSMessageWithWMSApi.WCSGetCheckDestinationAsync(inventoryStateBO.PalletBarcode, inventoryStateBO.EquipmentCode, inventoryStateBO.BatteryCode, inventoryStateBO.BatteryIndex);
                            if (uploaddataResult.Result == 66)
                            {

                            }
                        }
                        catch (Exception ex)
                        {
                            _logUtil.Error($"向WMS上传盘点托盘信息失败，调用接口WCSGetCheckDestinationAsync，异常信息{ex.Message}");
                            return;
                        }

                    }
                    #endregion



                    #region 取料判断为无料
                    if (inventoryStateBO.ActionType == 56)
                    {

                        /*上报WMS
                         *  返回结果 57=自动清楚 58=异常
                         *  参数
                            plccode：协议里面的plc设备编号
                            row:行
                            col：列
                            layer：层
                        */
                        WMSApiDomain.WebApi.HeaderResult<int> ClearOrAlarm = new WMSApiDomain.WebApi.HeaderResult<int>();
                        try
                        {
                            ClearOrAlarm = await WCSMessageWithWMSApi.WCSGetErrorResultAsync(inventoryStateBO.EquipmentCode, zJNScMessagePlcActionBO.StartlinetoPC, zJNScMessagePlcActionBO.StartcolumntoPC, zJNScMessagePlcActionBO.StartlayertoPC);
                        }
                        catch (Exception ex)
                        {
                            _logUtil.Error($"盘点取料判断向WMS上报设备号，行，列，层失败，接口WCSGetErrorResultAsync，异常信息{ex.Message}");
                            return;
                        }


                        if (ClearOrAlarm.Result == 57)
                        {
                            writeBo.ActionType = 57;

                            var res = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                            if (res)
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，回复57握手类型：自动清除，写入报文成功";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                            else
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.EquipmentCode}，回复57握手类型：自动清除，写入报文失败";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                return;
                            }
                        }
                        else if (ClearOrAlarm.Result == 58)
                        {
                            writeBo.ActionType = 58;

                            var res = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                            if (res)
                            {
                                //runLogInfo.RunLog = $"连接设备号{inventoryStateBO.PlcConnectionID}，回复58握手类型：异常堆垛机报警，写入报文成功";
                                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            }
                            else
                            {
                                runLogInfo.RunLog = $"连接设备号{inventoryStateBO.PlcConnectionID}，回复58握手类型：异常堆垛机报警，写入报文失败";
                                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                                return;
                            }

                        }

                    }
                    #endregion

                }

                #endregion

            }
        }


    }
}
